package net.spmiller;

import com.aetrion.flickr.Flickr;
import com.aetrion.flickr.FlickrException;
import com.aetrion.flickr.RequestContext;
import com.aetrion.flickr.auth.Auth;
import com.aetrion.flickr.auth.Permission;
import com.aetrion.flickr.photos.Exif;
import com.aetrion.flickr.photos.GeoData;
import com.aetrion.flickr.photos.Photo;
import com.aetrion.flickr.photos.PhotoList;
import com.aetrion.flickr.photos.geo.GeoInterface;
import net.spmiller.exception.FlickrInterfaceException;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.xml.sax.SAXException;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import static com.aetrion.flickr.Flickr.PRIVACY_LEVEL_NO_FILTER;

public class FlickrInterface {
    private static final Logger LOGGER = Logger.getLogger(FlickrInterface.class);
    private static final String API_KEY = "4300b56ec227f283072fa5719f1e59f5";
    private static final String SHARED_SECRET = "1de98e24e6a931dd";
    private Flickr flickr;

    public FlickrInterface() {
        this(new Flickr(API_KEY));
    }

    public FlickrInterface(Flickr flickr) {
        this.flickr = flickr;
        flickr.setSharedSecret(SHARED_SECRET);
        //flickr.debugStream = true;
        //flickr.debugRequest = true;
    }

    public void setLocations(Collection<FlickrPhoto> photos) {
        final GeoInterface geoInterface = flickr.getGeoInterface();

        final List<FlickrPhoto> failedPhotos = new ArrayList<FlickrPhoto>();
        for (FlickrPhoto photo : photos) {
            try {
                geoInterface.setLocation(photo.getFlickrId(), new GeoData(photo.getLocation().getLongitude(), photo.getLocation().getLatitude(), photo.getLocation().getGpsVersion()));
            } catch (Exception e) {
                LOGGER.debug("Problem updating GeoData for photo '" + photo + "'", e);
                failedPhotos.add(photo);
            }
        }

    }

    public List<FlickrPhoto> getUngeotaggedPhotos(String username) {
        final PhotoList photoList;
        try {
//            final String frob = flickr.getAuthInterface().getFrob();
//            final URL url = flickr.getAuthInterface().buildAuthenticationUrl(Permission.READ, frob);
//            System.out.println("url = " + url);
            //final String frob = "72157624938317734-b3b42437220da5cc-514169";
            //final Auth auth = flickr.getAuthInterface().getToken(frob);
            final Auth auth = new Auth();
            auth.setToken("72157624938296658-a828fc2d207ff980");
            RequestContext.getRequestContext().setAuth(auth);
            photoList = flickr.getPhotosInterface().getWithoutGeoData(new Date(0), new Date(), new Date(0), new Date(), PRIVACY_LEVEL_NO_FILTER, null, null, 100, 0);
        } catch (IOException e) {
            throw new FlickrInterfaceException(e);
        } catch (SAXException e) {
            throw new FlickrInterfaceException(e);
        } catch (FlickrException e) {
            throw new FlickrInterfaceException(e);
        }

        List<FlickrPhoto> photos = new ArrayList<FlickrPhoto>();

        for (Object object : photoList) {
            com.aetrion.flickr.photos.Photo photo = (Photo) object;

            final String uniqueId = getUniqueId(photo);

            if (StringUtils.isNotEmpty(uniqueId)) {
                final FlickrPhoto cleanPhoto = new FlickrPhoto(photo.getId(), uniqueId, photo.getUrl());
                photos.add(cleanPhoto);
            }

        }
        return photos;
    }

    private String getUniqueId(Photo photo) {
        try {
            final Collection<Exif> exifData = flickr.getPhotosInterface().getExif(photo.getId(), photo.getSecret());
            for (Exif exifField : exifData) {
                if ("ImageUniqueID".equals(exifField.getTag()) && "ExifIFD".equals(exifField.getTagspace())) {
                    return exifField.getRaw();
                }
            }
        } catch (Exception e) {
            throw new FlickrInterfaceException(e);
        }
        return null;
    }

    public FlickrConversation beginConversation() {
        final String frob;
        try {
            frob = flickr.getAuthInterface().getFrob();
        } catch (Exception e) {
            throw new FlickrInterfaceException(e);
        }
        return FlickrConversation.conversationFromFrob(frob);
    }

    public URL getAuthorisationUrl(FlickrConversation conversation) {
        try {
            return flickr.getAuthInterface().buildAuthenticationUrl(Permission.READ, conversation.getFrob());
        } catch (MalformedURLException e) {
            throw new FlickrInterfaceException(e);
        }
    }

    public void completeAuthorisation(FlickrConversation conversation) {
        try {
            final Auth auth = flickr.getAuthInterface().getToken(conversation.getFrob());
            conversation.authoriseConversation(auth.getToken());
        } catch (Exception e) {
            throw new FlickrInterfaceException(e);
        }
    }
}
